package com.hymjweb.demo.hymj.master_bill_manage.flight.service;

import com.alibaba.fastjson.JSONObject;
import com.hymjweb.demo.SpringAopUtil;
import com.hymjweb.demo.framework.result.MIniUIGridResultMap;
import com.hymjweb.demo.framework.sys.BaseService;
import com.hymjweb.demo.framework.sys.SysConstant;
import com.hymjweb.demo.framework.util.DataTypeUtil;
import com.hymjweb.demo.framework.util.DateUtil;
import com.hymjweb.demo.framework.util.DoubleUtil;
import com.hymjweb.demo.framework.util.util.PoiUtil;
import com.hymjweb.demo.hymj.basic_data_manage.xt_upload_file.bean.XtUploadFilePojo;
import com.hymjweb.demo.hymj.basic_data_manage.xt_upload_file.service.XtUploadFileService;
import com.hymjweb.demo.hymj.bill_code_manage.b_master.bean.BMasterBillCodePojo;
import com.hymjweb.demo.hymj.bill_code_manage.b_master.service.BMasterBillCodeService;
import com.hymjweb.demo.hymj.log_manage.aop.annotation.OperationLogger;
import com.hymjweb.demo.hymj.master_bill_manage.flight.bean.BMasterBillFlightBean;
import com.hymjweb.demo.hymj.master_bill_manage.flight.bean.BMasterBillFlightPojo;
import com.hymjweb.demo.hymj.master_bill_manage.load.bean.BNativeBillLoadPojo;
import com.hymjweb.demo.hymj.master_bill_manage.flight.mapper.BMasterBillFlightMapper;
import com.hymjweb.demo.hymj.master_bill_manage.load.service.BNativeBillLoadService;
import com.hymjweb.demo.hymj.master_bill_manage.other_charges.bean.BMasterBillOtherChargePojo;
import com.hymjweb.demo.hymj.master_bill_manage.other_charges.service.BMasterBillOtherChargeService;
import com.hymjweb.demo.hymj.master_bill_manage.pull.bean.BMasterBillPullPojo;
import com.hymjweb.demo.hymj.master_bill_manage.pull.detail.bean.BMasterBillPullDetailPojo;
import com.hymjweb.demo.hymj.master_bill_manage.pull.detail.service.BMasterBillPullDetailService;
import com.hymjweb.demo.hymj.master_bill_manage.pull.service.BMasterBillPullService;
import com.hymjweb.demo.hymj.native_bill_manage.bean.BNativeBillPojo;
import com.hymjweb.demo.hymj.native_bill_manage.pull_cost.bean.BNativeBillPullCostPojo;
import com.hymjweb.demo.hymj.native_bill_manage.pull_cost.service.BNativeBillPullCostService;
import com.hymjweb.demo.hymj.native_bill_manage.service.BNativeBillService;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

@Service
public class BMasterBillFlightService extends BaseService {

    @Autowired
    private BMasterBillFlightMapper bMasterBillFlightMapper;

    @Autowired
    private BMasterBillOtherChargeService bMasterBillOtherChargeService;

    @Autowired
    private BMasterBillCodeService bMasterBillCodeService;

    @Autowired
    private BNativeBillLoadService bNativeBillLoadService;

    @Autowired
    private BNativeBillService bNativeBillService;

    @Autowired
    private BMasterBillPullService bMasterBillPullService;

    @Autowired
    private BMasterBillPullDetailService bMasterBillPullDetailService;

    @Autowired
    private BNativeBillPullCostService bNativeBillPullCostService;

    @Autowired
    private XtUploadFileService xtUploadFileService;

    public static final int MASTER_BILL_EXSIT = -10; // 分单已经存在

    public static final int OP_FAIL = 0; //操作失败

    private static final Double DEFAULT_AMOUNT = -999999999D;

    /**
     * 航空主单位 json 对象转 java 对象
     *
     * @param jsonMasterBillPojo 主单json 对象
     * @return 返回主单java 对象
     */
    public BMasterBillFlightBean convertJSONObjToJavaObj(JSONObject jsonMasterBillPojo) {
        BMasterBillFlightBean bean = new BMasterBillFlightBean();
        // 航空主单号 ID
        String id = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("billId"));
        bean.setId(id);

        // 承运方式ID
        Long transportWayId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("transportWayId"));
        bean.setTransportWayId(transportWayId);

        // 外发单位ID
        String outUnitId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("outUnitId"));
        bean.setOutUnitId(outUnitId);

        //航班日期
        Date flightDate = DateUtil.strToDate(DataTypeUtil.toStringObject(jsonMasterBillPojo.get("flightDate")));
        bean.setFlightDate(flightDate);

        // 航空公司ID
        String airlinesId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("airlinesId"));
        bean.setAirlinesId(airlinesId);

        // 配货方式ID
        Long loadWayId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("loadWayId"));
        bean.setLoadWayId(loadWayId);

        // 货物类型ID
        Long goodsTypeId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("goodsTypeId"));
        bean.setGoodsTypeId(goodsTypeId);

        // 始发机场 ID
        String airportId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("airportId"));
        bean.setAirportId(airportId);

        // 目的市ID
        String destCityId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("destCityId"));
        bean.setDestCityId(destCityId);

        // 班次号
        String flightNo = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("flightNo"));
        bean.setFlightNo(flightNo);

        // 班次名
        String flightName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("flightName"));
        bean.setFlightName(flightName);

        // 计划出发时间
        String planTakeOffTime = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("planTakeOffTime"));
        bean.setPlanTakeOffTime(planTakeOffTime);

        // 发货公司ID
        String agentCompanyId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("agentCompanyId"));
        bean.setAgentCompanyId(agentCompanyId);

        // 发货公司名称
        String agentCompanyName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("agentCompanyName"));
        bean.setAgentCompanyName(agentCompanyName);

        // 发货公司电话
        String agentCompanyPhone = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("agentCompanyPhone"));
        bean.setAgentCompanyPhone(agentCompanyPhone);

        // 发货公司地址
        String agentCompanyAddress = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("agentCompanyAddress"));
        bean.setAgentCompanyAddress(agentCompanyAddress);

        // 收货客户ID
        String receiveCustomerId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("receiveCustomerId"));
        bean.setReceiveCustomerId(receiveCustomerId);

        // 收货客户名称
        String receiveCustomerName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("receiveCustomerName"));
        bean.setReceiveCustomerName(receiveCustomerName);

        // 收货客户电话
        String receiveCustomerPhone = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("receiveCustomerPhone"));
        bean.setReceiveCustomerPhone(receiveCustomerPhone);

        // 收货客户地址
        String receiveCustomerAddress = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("receiveCustomerAddress"));
        bean.setReceiveCustomerAddress(receiveCustomerAddress);

        // 运价种类ID
        Long freightSpeciesId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("freightSpeciesId"));
        bean.setFreightSpeciesId(freightSpeciesId);

        // 商品代号ID
        Long goodsCodeId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("goodsCodeId"));
        bean.setGoodsCodeId(goodsCodeId);

        // 货物名称
        String goodsName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("goodsName"));
        bean.setGoodsName(goodsName);

        // 包装方式ID
        Long packingWayId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("packingWayId"));
        bean.setPackingWayId(packingWayId);

        // 总件数
        Long totalNumber = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("totalNumber"));
        bean.setTotalNumber(totalNumber);

        // 实际重量
        Double actualWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("actualWeight"));
        bean.setActualWeight(actualWeight);

        // 计费重量
        Double chargeableWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("chargeableWeight"));
        bean.setChargeableWeight(chargeableWeight);

        // 实际配载重量
        Double actualLoadTotalWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("actualLoadTotalWeight"));
        bean.setActualLoadTotalWeight(actualLoadTotalWeight);

        // 重量费率
        Double weightRate = DataTypeUtil.toDouble(jsonMasterBillPojo.get("weightRate"));
        bean.setWeightRate(weightRate);

        // 航空运费
        Double transportCost = DataTypeUtil.toDouble(jsonMasterBillPojo.get("transportCost"));
        bean.setTransportCost(transportCost);

        // 航空运费调整金额
        Double pullDisposeTransportCostAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("pullDisposeTransportCostAmount"));
        bean.setPullDisposeTransportCostAmount(pullDisposeTransportCostAmount);

        // 航空运费对账状态ID
        Long transportCostAccountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("transportCostAccountCheckStatusId"));
        bean.setTransportCostAccountCheckStatusId(transportCostAccountCheckStatusId);

        // 计算重量分类
        Long calcWeightCategoryId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("calcWeightCategoryId"));
        bean.setCalcWeightCategoryId(calcWeightCategoryId);

        // 机场货站ID
        String airportGoodsSiteId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("airportGoodsSiteId"));
        bean.setAirportGoodsSiteId(airportGoodsSiteId);

        // 声明价值
        Double declaredValue = DataTypeUtil.toDouble(jsonMasterBillPojo.get("declaredValue"));
        bean.setDeclaredValue(declaredValue);

        // 地面运费
        Double groundAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("groundAmount"));
        bean.setGroundAmount(groundAmount);

        // 地面运费调整金额
        Double pullDisposeGroundAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("pullDisposeGroundAmount"));
        bean.setPullDisposeGroundAmount(pullDisposeGroundAmount);

        // 地面运费对账状态ID
        Long groundAmountAccountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("groundAmountAccountCheckStatusId"));
        bean.setGroundAmountAccountCheckStatusId(groundAmountAccountCheckStatusId);


        // 印花税
        Double stampDuty = DataTypeUtil.toDouble(jsonMasterBillPojo.get("stampDuty"));
        bean.setStampDuty(stampDuty);

        // 保险费
        Double insuranceFee = DataTypeUtil.toDouble(jsonMasterBillPojo.get("insuranceFee"));
        bean.setInsuranceFee(insuranceFee);

        // 航空附加费
        Double airlinesAddCost = DataTypeUtil.toDouble(jsonMasterBillPojo.get("airlinesAddCost"));
        bean.setAirlinesAddCost(airlinesAddCost);

        // 航空附加费用调整金额
        Double pullDisposeAirlinesAddCostAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("pullDisposeAirlinesAddCostAmount"));
        bean.setPullDisposeAirlinesAddCostAmount(pullDisposeAirlinesAddCostAmount);

        // 航空附加费对账状态ID
        Long airlinesAddCostAccountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("airlinesAddCostAccountCheckStatusId"));
        bean.setAirlinesAddCostAccountCheckStatusId(airlinesAddCostAccountCheckStatusId);

        // 其他费用
        Double otherCharges = DataTypeUtil.toDouble(jsonMasterBillPojo.get("otherCharges"));
        bean.setOtherCharges(otherCharges);

        // 其他费用说明
        String otherChargesComment = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("otherChargesComment"));
        bean.setOtherChargesComment(otherChargesComment);

        // 其他费用调整金额
        Double pullDisposeOtherChargesAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("pullDisposeOtherChargesAmount"));
        bean.setPullDisposeOtherChargesAmount(pullDisposeOtherChargesAmount);

        // 其他费用费对账状态ID
        Long otherChargesAccountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("otherChargesAccountCheckStatusId"));
        bean.setOtherChargesAccountCheckStatusId(otherChargesAccountCheckStatusId);

        // 付款方式ID
        Long masterBillPaymentMethodId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("masterBillPaymentMethodId"));
        bean.setMasterBillPaymentMethodId(masterBillPaymentMethodId);

        // 总金额
        Double totalAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("totalAmount"));
        bean.setTotalAmount(totalAmount);

        // 拉货调整金额
        // Double dropAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("dropAmount"));
        Double dropAmount = DataTypeUtil.toDouble(pullDisposeTransportCostAmount + pullDisposeGroundAmount + pullDisposeAirlinesAddCostAmount + pullDisposeOtherChargesAmount, 2);
        bean.setDropAmount(dropAmount);

        // 结算金额
        Double settlementAmount = DoubleUtil.sum(totalAmount, dropAmount, 2);
        bean.setSettlementAmount(settlementAmount);

        // 开单日期
        Date openMasterBillDate = DateUtil.strToDate(DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillDate")));
        bean.setOpenMasterBillDate(openMasterBillDate);

        // 开单部门ID
        String openMasterBillDepartmentId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillDepartmentId"));
        bean.setOpenMasterBillDepartmentId(openMasterBillDepartmentId);

        // 开单人ID
        String openMasterBillUserId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillUserId"));
        bean.setOpenMasterBillUserId(openMasterBillUserId);

        // 运费结清状态ID
        Long transportCostStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("transportCostStatusId"));
        bean.setTransportCostStatusId(transportCostStatusId);

        // 地面运费结清状态 ID
        Long groundAmountStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("groundAmountStatusId"));
        bean.setGroundAmountStatusId(groundAmountStatusId);

        // 航空附加费用结算状态 ID
        Long airlinesAddCostStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("airlinesAddCostStatusId"));
        bean.setAirlinesAddCostStatusId(airlinesAddCostStatusId);

        // 其他费用结算状态 ID
        Long otherChargesStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("otherChargesStatusId"));
        bean.setOtherChargesStatusId(otherChargesStatusId);

        // 拉货状态
        Long dropStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("dropStatusId"));
        bean.setDropStatusId(dropStatusId);


        // 对账状态
        Long accountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("accountCheckStatusId"));
        bean.setAccountCheckStatusId(accountCheckStatusId);

        // 结算状态
        Long settlementStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("settlementStatusId"));
        bean.setSettlementStatusId(settlementStatusId);

        // 备注
        String comment = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("comment"));
        bean.setComment(comment);

        // 配载的分单号
        String loadNativeBillIds = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("loadNativeBillIds"));
        bean.setLoadNativeBillIds(loadNativeBillIds);

        // 创建时间
        Date currentDateTime = DateUtil.getSysDateTime();
        // 创建人
        String createUserId = getLoginCzyId();
        bean.setCreateTime(currentDateTime);
        bean.setCreateUserId(createUserId);
        bean.setUpdateTime(currentDateTime);
        bean.setUpdateUserId(createUserId);

        // 获取其他费用列表
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = null;
        List<Map> otherChargeList = (List<Map>) jsonMasterBillPojo.get("otherChargeList");
        if (otherChargeList != null && otherChargeList.size() > 0) {
            bMasterBillOtherChargePojos = new ArrayList<>();
            for (Map map : otherChargeList) {
                BMasterBillOtherChargePojo bMasterBillOtherChargePojo = new BMasterBillOtherChargePojo();
                bMasterBillOtherChargePojo.setId(this.getSysStrId());
                // 设置主单其他费用类型
                bMasterBillOtherChargePojo.setMasterBillTypeId(SysConstant.XT_DIC_MASTER_BILL_TYPE.FLIGHT.getId());
                bMasterBillOtherChargePojo.setMasterBillId(bean.getId());
                bMasterBillOtherChargePojo.setName(DataTypeUtil.toStringObject(map.get("name")));
                bMasterBillOtherChargePojo.setAmount(DataTypeUtil.toDouble(map.get("amount")));
                bMasterBillOtherChargePojo.setComment(DataTypeUtil.toStringObject(map.get("comment")));
                bMasterBillOtherChargePojos.add(bMasterBillOtherChargePojo);
            }
        }

        bean.setBMasterBillOtherChargePojos(bMasterBillOtherChargePojos);


        // 获取加入主单的分单信息
        List<BNativeBillLoadPojo> bNativeBillLoadPojos = null;
        List<Map> nativeBillList = (List<Map>) jsonMasterBillPojo.get("nativeBillList");
        if (nativeBillList != null && nativeBillList.size() > 0) {
            bNativeBillLoadPojos = new ArrayList<>();
            for (Map map : nativeBillList) {
                BNativeBillLoadPojo bNativeBillLoadPojo = new BNativeBillLoadPojo();

                bNativeBillLoadPojo.setId(this.getSysStrId());
                // 设置配载表主单ID
                bNativeBillLoadPojo.setMasterBillId(bean.getId());
                // 设置配载的主单类型
                bNativeBillLoadPojo.setMasterBillTypeId(SysConstant.XT_DIC_MASTER_BILL_TYPE.FLIGHT.getId());
                // 设置配载表分单ID
                bNativeBillLoadPojo.setNativeBillId(DataTypeUtil.toStringObject(map.get("id")));
                // 航空公司ID
                bNativeBillLoadPojo.setAirlinesId(DataTypeUtil.toStringObject(map.get("airlinesId")));
                // 航班ID
                bNativeBillLoadPojo.setFlightNo(DataTypeUtil.toStringObject(map.get("flightNo")));
                // 航班名称
                bNativeBillLoadPojo.setFlightName(DataTypeUtil.toStringObject(map.get("flightName")));
                // 航班日期  flightDate -> 2021-03-03T16:00:00.000+0000
                bNativeBillLoadPojo.setFlightDate(DateUtil.strToDate(DataTypeUtil.toStringObject(map.get("flightDate"))));
                // 配载件数
                bNativeBillLoadPojo.setLoadNumber(DataTypeUtil.toLongObject(map.get("totalNumber")));
                // 配载实重
                bNativeBillLoadPojo.setLoadActualWeight(DataTypeUtil.toDouble(map.get("actualWeight")));
                // 配载计重
                bNativeBillLoadPojo.setLoadChargeableWeight(DataTypeUtil.toDouble(map.get("chargeableWeight")));
                // 配置载体积
                bNativeBillLoadPojo.setLoadVolume(DataTypeUtil.toDouble(map.get("volume")));
                // 分摊主单航空运费成本
                bNativeBillLoadPojo.setShareTransportCostAmount(0D);
                // 分摊主单地面运费成本
                bNativeBillLoadPojo.setShareGroundAmount(0D);
                // 分摊航空附加费成本
                bNativeBillLoadPojo.setShareAirlinesAddCostAmount(0D);
                // 分摊其他费用成本
                bNativeBillLoadPojo.setShareOtherChargesAmount(0D);
                // 分摊总成本
                bNativeBillLoadPojo.setShareTotalCostAmount(0D);
                // 分摊总本说明
                bNativeBillLoadPojo.setShareTotalCostComment("");

                // 对象加入到配载列表
                bNativeBillLoadPojos.add(bNativeBillLoadPojo);
            }
        }

        bean.setBNativeBillLoadPojos(bNativeBillLoadPojos);

        return bean;
    }

    /**
     * 根据主单号id,返回主单对象
     *
     * @param id 主单号
     * @return 航空主单对象
     */
    public BMasterBillFlightPojo getBMasterBillFlightPojoById(String id) {
        return bMasterBillFlightMapper.getBMasterBillFlightPojoById(id);
    }

    //@OperationLogger(oper = SysConstant.OPER_ADD, operTitle = "航空主单-添加", operMemo = "", classType = BMasterBillFlightPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int insert(BMasterBillFlightPojo pojo) throws Exception {
        if (pojo == null) {
            throwException("添加航空主单参数错误!");
        }
        Date nowTime = this.getSysTime();
        String czyId = this.getLoginCzyId();
        pojo.setCreateTime(nowTime);
        pojo.setCreateUserId(czyId);
        pojo.setUpdateTime(nowTime);
        pojo.setUpdateUserId(czyId);

        return bMasterBillFlightMapper.insert(pojo);
    }


    /**
     * 更新主单对象
     *
     * @param bMasterBillFlightPojo
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updatePojo(BMasterBillFlightPojo bMasterBillFlightPojo) throws Exception {
        if (bMasterBillFlightPojo == null) {
            throwException("更新主单参数错误!");
        }
        bMasterBillFlightPojo.setUpdateTime(this.getSysTime());
        bMasterBillFlightPojo.setUpdateUserId(this.getLoginCzyId());
        return bMasterBillFlightMapper.updatePojo(bMasterBillFlightPojo);
    }


    /**
     * 添加航空主单及配载信息，同时更新主单号使用状态
     *
     * @param bMasterBillFlightBean 航空主单对象
     * @return 添加时影响的行数，如果为0,则表示添加失败，否则表示添加成功
     */
    @Transactional(rollbackFor = {Exception.class})
    public int addMasterFlightBill(BMasterBillFlightBean bMasterBillFlightBean) throws Exception {

        if (bMasterBillFlightBean == null) {
            throwException("添加主单参数错误!");
        }

        // 检测主单号是否重复
        BMasterBillFlightPojo bMasterBillFlightPojo = bMasterBillFlightMapper.getBMasterBillFlightPojoById(bMasterBillFlightBean.getId());

        if (bMasterBillFlightPojo != null) {
            return BMasterBillFlightService.MASTER_BILL_EXSIT;
        }

        if (bMasterBillFlightBean.getChargeableWeight() <= SysConstant.ZERO) {
            throwException("主单计费重量不能小于或等于零!");
        }

        // 修正主单入库状态
        changeAccountCheckAndSetllementStatus(bMasterBillFlightBean);

        // 可以入库
        // 1.先入库航空主单对象
        int affectRows = SpringAopUtil.getBean(this.getClass()).insert(bMasterBillFlightBean);
        if (affectRows <= SysConstant.INT_ZERO) {
            return SysConstant.INT_ZERO;
        }
        // 2.入库航空主单其他费用
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = bMasterBillFlightBean.getBMasterBillOtherChargePojos();
        if (bMasterBillOtherChargePojos != null && !bMasterBillOtherChargePojos.isEmpty()) {
            int otherChargeEffectRows = bMasterBillOtherChargeService.batchInsert(bMasterBillOtherChargePojos);
            if (otherChargeEffectRows == BMasterBillFlightService.OP_FAIL) {
                return BMasterBillFlightService.OP_FAIL;
            }
        }

        // 3.入库主单关联配置的分单列表
        List<BNativeBillLoadPojo> bNativeBillLoadPojos = bMasterBillFlightBean.getBNativeBillLoadPojos();
        if (bNativeBillLoadPojos != null && !bNativeBillLoadPojos.isEmpty()) {
            // 批量插入配载的分单
            int loadEffectRows = bNativeBillLoadService.batchInsertLoadBill(bNativeBillLoadPojos);
            if (loadEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }

            // 获取分单成本与利润核算标准
            Integer costShareStandard = getCostShareStandard(bMasterBillFlightBean, bNativeBillLoadPojos);

            // 配载分单成本核算
            for (BNativeBillLoadPojo pojo : bNativeBillLoadPojos) {
                bNativeBillLoadService.loadNativeBillCostAccounting(pojo, costShareStandard);
            }

            // 原始分单成本、利润核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojos) {
                int nativeUpdateAffectRows = bNativeBillService.nativeBillCostAccounting(loadPojo.getNativeBillId(), false);
            }
        }

        // 5.标识主单号使用状态,需要注意的是，如果的外发的单子不用更新，因为外发主单号不在主单号表中存在的,如果是外发的则不用处理状态了
        if (bMasterBillFlightBean.getTransportWayId().longValue() == SysConstant.XT_DIC_TRANSPORT_WAY.SELF.getId()) {
            int masterCodeStatusEffectRows = bMasterBillCodeService.updateUseStatus(bMasterBillFlightBean.getId(), SysConstant.XT_DIC_USE_STATUS.USED.getId(), this.getSystemUserDepartment().getId(), this.getLoginCzyId());
            if (masterCodeStatusEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }

        return affectRows;
    }

    private void changeAccountCheckAndSetllementStatus(BMasterBillFlightBean bMasterBillFlightBean) {

        // 航空运费对账状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getTransportCost(), bMasterBillFlightBean.getPullDisposeTransportCostAmount(), 2) == SysConstant.ZERO) {
            bMasterBillFlightBean.setTransportCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }
        else{
            bMasterBillFlightBean.setTransportCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId());
        }

        // 地面运费对账状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getGroundAmount(), bMasterBillFlightBean.getPullDisposeGroundAmount(), 2) == SysConstant.ZERO) {
            bMasterBillFlightBean.setGroundAmountAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }
        else{
            bMasterBillFlightBean.setGroundAmountAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId());
        }

        // 航空附加费用对账状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getAirlinesAddCost(), bMasterBillFlightBean.getPullDisposeAirlinesAddCostAmount(), 2) == SysConstant.ZERO) {
            bMasterBillFlightBean.setAirlinesAddCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }
        else{
            bMasterBillFlightBean.setAirlinesAddCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId());
        }

        // 其他费用对账状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getOtherCharges(), bMasterBillFlightBean.getPullDisposeOtherChargesAmount(), 2) == SysConstant.ZERO) {
            bMasterBillFlightBean.setOtherChargesAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
        }
        else{
            bMasterBillFlightBean.setOtherChargesAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId());
        }

        // 调整航空地面运费的状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getGroundAmount().doubleValue(),bMasterBillFlightBean.getPullDisposeGroundAmount(),2) > SysConstant.ZERO.doubleValue()) {
            bMasterBillFlightBean.setGroundAmountStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }
        else{
            bMasterBillFlightBean.setGroundAmountStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }

        // 调整航空运费的状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getTransportCost().doubleValue(),bMasterBillFlightBean.getPullDisposeTransportCostAmount().doubleValue(),2) > SysConstant.ZERO.doubleValue()) {
            bMasterBillFlightBean.setTransportCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }
        else{
            bMasterBillFlightBean.setTransportCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }

        // 航空附加费用的状态
        if (DoubleUtil.sum(bMasterBillFlightBean.getAirlinesAddCost().doubleValue(),bMasterBillFlightBean.getPullDisposeAirlinesAddCostAmount().longValue(),2) > SysConstant.ZERO.doubleValue()) {
            bMasterBillFlightBean.setAirlinesAddCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }
        else{
            bMasterBillFlightBean.setAirlinesAddCostStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }

        // 航空其他费结算状态
        if(DoubleUtil.sum(bMasterBillFlightBean.getOtherCharges().doubleValue(),bMasterBillFlightBean.getPullDisposeOtherChargesAmount(),2) > SysConstant.ZERO.doubleValue()){
            bMasterBillFlightBean.setOtherChargesStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());
        }
        else{
            bMasterBillFlightBean.setOtherChargesStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }

    }

    public Integer getCostShareStandard(BMasterBillFlightPojo bMasterBillFlightPojo, List<BNativeBillLoadPojo> bNativeBillLoadPojos) {
        // 遍历一下，瞧一瞧整体或个体重量是否超过主单计费重量
        Double loadPojoTotalActualWeight = 0D;
        for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojos) {
            loadPojoTotalActualWeight += loadPojo.getLoadActualWeight();
        }

        Integer costShareStandard = SysConstant.COST_SHARE_STANDARD_WEIGHT;
        if (loadPojoTotalActualWeight > bMasterBillFlightPojo.getActualLoadTotalWeight()) {
            costShareStandard = SysConstant.COST_SHARE_STANDARD_NUMBER;
        }
        return costShareStandard;
    }


    /**
     * 根据查询条件参数，查询返回的结果列表
     *
     * @param param 条件参数
     * @return 主单列表对象
     */
    public Object getPageList(Map param) {
        this.pageListInit(param);
        List list = bMasterBillFlightMapper.findAll(param);
        MIniUIGridResultMap resultMap = this.pageToGrid(list);
        return resultMap;
    }

    public List<BMasterBillFlightPojo> getBMasterBillFlightPojoListByInId(String billIds) throws Exception {
        if (DataTypeUtil.isEmptyStr(billIds)) {
            throwException("获取主单列表参数错误!");
        }
        return bMasterBillFlightMapper.getBMasterBillFlightPojoListByInId(billIds);
    }


    /**
     * 更新主单业务方法
     *
     * @param bMasterBillFlightBean 待更新的主单对象
     * @return 更新后影响的行数
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateMasterFlightBill(BMasterBillFlightBean bMasterBillFlightBean) throws Exception {

        if (bMasterBillFlightBean == null) {
            throwException("更新主单参数错误!");
        }

        if (bMasterBillFlightBean.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
            throwException("主单已经做过拉货操作，不能进行更新操作!");
        }

        changeAccountCheckAndSetllementStatus(bMasterBillFlightBean);

        // 航空运费对账状态
//        if (DoubleUtil.sum(bMasterBillFlightBean.getTransportCost(), bMasterBillFlightBean.getPullDisposeTransportCostAmount(), 2) == SysConstant.ZERO) {
//            bMasterBillFlightBean.setTransportCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
//        }
//
//        // 地面运费对账状态
//        if (DoubleUtil.sum(bMasterBillFlightBean.getGroundAmount(), bMasterBillFlightBean.getPullDisposeGroundAmount(), 2) == SysConstant.ZERO) {
//            bMasterBillFlightBean.setGroundAmountAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
//        }
//
//        // 航空附加费用对账状态
//        if (DoubleUtil.sum(bMasterBillFlightBean.getAirlinesAddCost(), bMasterBillFlightBean.getPullDisposeAirlinesAddCostAmount(), 2) == SysConstant.ZERO) {
//            bMasterBillFlightBean.setAirlinesAddCostAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
//        }
//
//        // 其他费用对账状态
//        if (DoubleUtil.sum(bMasterBillFlightBean.getOtherCharges(), bMasterBillFlightBean.getPullDisposeOtherChargesAmount(), 2) == SysConstant.ZERO) {
//            bMasterBillFlightBean.setOtherChargesAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
//        }

        // 设置更新时间与更新人
        bMasterBillFlightBean.setUpdateTime(DateUtil.getSysDateTime());
        bMasterBillFlightBean.setUpdateUserId(this.getLoginCzyId());
        // 开始更新
        int effectRows = SpringAopUtil.getBean(this.getClass()).updatePojo(bMasterBillFlightBean);
        if (effectRows == SysConstant.INT_ZERO) {
            return SysConstant.INT_ZERO;
        }

        // 2.更新航空主单其他费用
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = bMasterBillFlightBean.getBMasterBillOtherChargePojos();
        if (bMasterBillOtherChargePojos != null && bMasterBillOtherChargePojos.size() > 0) {
            // 2.1 先删除航空主单位原来的其他费用
            int delChargeEffectRows = bMasterBillOtherChargeService.deleteByMasterBillId(bMasterBillFlightBean.getId());

            // 2.2 重新插入最新的其他费用
            int otherChargeEffectRows = bMasterBillOtherChargeService.batchInsert(bMasterBillOtherChargePojos);
            if (otherChargeEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }

        // 3.更新主单包含的分单信息
        List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bMasterBillFlightBean.getBNativeBillLoadPojos();
        if (bNativeBillLoadPojoList != null && !bNativeBillLoadPojoList.isEmpty()) {
            // 3.1 删除原来的主单包含的分单
            int delLoadEffectRows = bNativeBillLoadService.deleteLoadNativeBillByMasterBillId(bMasterBillFlightBean.getId());

            // 3.2 重新插入主单包含的最新的分单
            int loadEffectRows = bNativeBillLoadService.batchInsertLoadBill(bNativeBillLoadPojoList);
            if (loadEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }

            Integer costShareStandard = getCostShareStandard(bMasterBillFlightBean, bNativeBillLoadPojoList);

            // 3.3 对新插入的配载分单重新进行成本核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                bNativeBillLoadService.loadNativeBillCostAccounting(loadPojo, costShareStandard);
            }

            // 3.4 对配载分单的原始分单进行成本核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                bNativeBillService.nativeBillCostAccounting(loadPojo.getNativeBillId(), false);
            }

        }

        // 4.主单号的使用部门与使用人更新一下
        // 自发的主单需要更新主单使用情况，外发不需要，因为外发没有记录相应的单号
        if (bMasterBillFlightBean.getTransportWayId().longValue() == SysConstant.XT_DIC_TRANSPORT_WAY.SELF.getId()) {
            int masterCodeStatusEffectRows = bMasterBillCodeService.updateUseStatus(bMasterBillFlightBean.getId(), SysConstant.XT_DIC_USE_STATUS.USED.getId(), this.getSystemUserDepartment().getId(), this.getLoginCzyId());
            if (masterCodeStatusEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }

        return effectRows;
    }

    /**
     * 查询主单包含的分单
     *
     * @param param
     * @return
     */
    public Object queryNativeBillList(Map param) {
        return bNativeBillLoadService.queryNativeBillList(param);
    }

    /**
     * 这个查询不分页
     *
     * @param param1
     * @return
     */
    public List<BNativeBillLoadPojo> queryNativeBillListNoPage(Map<String, Object> param1) {
        return bNativeBillLoadService.queryNativeBillListNoPage(param1);
    }


    /**
     * 更新分状态，根据 billIds,格式如 'aa','bb','cc'
     *
     * @param statusFieldName
     * @param billIds
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateStatusId(String statusFieldName, Long statusId, String billIds) {
        return bMasterBillFlightMapper.updateStatusId(statusFieldName, statusId, billIds, this.getSysTime(), this.getLoginCzyId());
    }

    @Transactional(rollbackFor = {Exception.class})
    public int changeAccountCheckStatus(Map param) throws Exception {
        if (param == null || param.isEmpty()) {
            throwException("更新主单状态参数错误!");
        }
        // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus}
        Long accountCheckStatusId = DataTypeUtil.toLongObject(param.get("accountCheckStatusId"));
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));

        if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId()) {
            List<BMasterBillFlightPojo> list = getBMasterBillFlightPojoListByInId(billIds);
            String ids = "";
            for (BMasterBillFlightPojo pojo : list) {
                if (pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()) {
                    ids += pojo.getId() + " ";
                }
            }
            if (ids.length() > 0) {
                ids = ids.trim();
                throw new Exception("空运主单【" + ids + "】结算状态为已结算，不能修改其对账状态为未对账!");
            }
        }
        return updateStatusId("account_check_status_id", accountCheckStatusId, billIds);
    }


    @Transactional(rollbackFor = {Exception.class})
    public int changeAccountCheckStatusByAccountType(Map param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("更新主单状态参数错误!");
        }
        // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus,accountTypeId:accountType}
        Long accountTypeId = DataTypeUtil.toLongObject(param.get("accountTypeId"));
        Long accountCheckStatusId = DataTypeUtil.toLongObject(param.get("accountCheckStatusId"));
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));

        /**
         * 主单运费、地面操作费、航空附加费、其他费用对账
         * accountType:
         * 0:航空运费
         * 1:地面操作费
         * 2:航空附加费
         * 3:其他费用
         */
        String title="";
        String fieldName = "";
        if(accountTypeId.longValue() == 0L){
            title = "航空运费";
            fieldName="transport_cost_account_check_status_id";
        }
        else if(accountTypeId.longValue() == 1L){
            title = "地面操作费";
            fieldName="ground_amount_account_check_status_id";
        }
        else if(accountTypeId.longValue() == 2L){
            title = "航空附加费";
            fieldName="airlines_add_cost_account_check_status_id";
        }
        else{
            title = "其他费用";
            fieldName="other_charges_account_check_status_id";
        }

        if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId()) {
            List<BMasterBillFlightPojo> list = getBMasterBillFlightPojoListByInId(billIds);
            String ids = "";
            for (BMasterBillFlightPojo pojo : list) {
                if (pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()) {
                    ids += pojo.getId() + " ";
                }
            }
            if (ids.length() > 0) {
                ids = ids.trim();
                throw new Exception("空运主单【" + ids + "】结算状态为已结算，不能修改" + title + "对账状态为未对账!");
            }
        }

        int affectRows = updateStatusId(fieldName, accountCheckStatusId, billIds);

        // 如果主单所有对账全部通过，则自动完成主单对账，不需要人工再做一次了
        List<BMasterBillFlightPojo> flightPojoList = this.bMasterBillFlightMapper.getBMasterBillFlightPojoListByInId(billIds);
        for(BMasterBillFlightPojo flightPojo : flightPojoList){
            Long transportCostAccountCheckStatusId = flightPojo.getTransportCostAccountCheckStatusId();
            Long groundAmountAccountCheckStatusId = flightPojo.getGroundAmountAccountCheckStatusId();
            Long airlinesAddCostAccountCheckStatusId = flightPojo.getAirlinesAddCostAccountCheckStatusId();
            Long otherChargesAccountCheckStatusId = flightPojo.getOtherChargesAccountCheckStatusId();
            Long masterBillAccountCheckStatusId = flightPojo.getAccountCheckStatusId();

            if(transportCostAccountCheckStatusId==SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    && groundAmountAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    && airlinesAddCostAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    && otherChargesAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    && masterBillAccountCheckStatusId ==SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId()
            ){
                // 设置主单对象的对账状态为已对账
                flightPojo.setAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId());
                // 更新 flightPojo 对象
                updatePojo(flightPojo);
            }

        }

        return affectRows;
    }


    /**
     * 空运主单分本分摊操作
     * 分单成本 = 主单的结算金额 * 分单对应的计费重量的百分比
     * <p>
     * A001  1000   主单的结算金额
     * 1001   200  = 1000 *   200/(200+50+300)
     * 1002   50    = 1000 *   50/(200+50+300)
     * 1003   300   = 1000 *   300/(200+50+300)
     * <p>
     * A002  300 主单的结算金额
     * 1001   20 = 300 * 20/70
     * 1002  50 = 300 * 50/70
     * <p>
     * 1001 分单分摊成本 = 1000 *   200/(200+50+300) + 300 * 20/70
     * <p>
     * 分单利润(不包含操作费) = 分单结算金额 - 业务费 - 结算送货费 - 分单分摊成本
     *
     * @param param
     * @return
     */
    @Deprecated
    public int costAllocation(Map param) throws Exception {
        //{masterBillIds:masterBillIdArray}
        if (param == null || param.size() == 0) {
            throw new Exception("空运主单成本分摊操作参数错误!");
        }

        // 获取所有需要分摊分成的主单号列表
        List<String> masterBillIdList = (List<String>) param.get("masterBillIds");

        // 把单号连接成 'dh1','dh2' 格式
        String masterBillIds = connectIds(masterBillIdList);

        // 1.获取所有的主单对象
        List<BMasterBillFlightPojo> masterBillFlightPojoList = bMasterBillFlightMapper.getBMasterBillFlightPojoListByInId(masterBillIds);

        if (masterBillFlightPojoList == null || masterBillFlightPojoList.isEmpty()) {
            throw new Exception("获取分摊主单对象为空，主单成本分摊操作失败!");
        }

        // 2.通过主单号批量获取对应的分单配载信息(这是指哪些分单被配载到哪些主单上，且各自的配载重量是多少)
        List<BNativeBillLoadPojo> nativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListByInMasterBillId(masterBillIds);
        if (nativeBillLoadPojoList == null || nativeBillLoadPojoList.isEmpty()) {
            throw new Exception("获取分单配载信息为空，成本分摊操作失败!");
        }

        // 3.获取所有需要分摊的分单对象,先需要从配置对象中去重
        Set<String> billIdSet = new HashSet<>();
        for (BNativeBillLoadPojo pojo : nativeBillLoadPojoList) {
            billIdSet.add(pojo.getNativeBillId());
        }

        if (billIdSet.isEmpty()) {
            throw new Exception("获取分单配载信息为空，成本分摊操作失败!");
        }

        // 分单号去重后，进行连接 'dh1','dh2'
        String billIds = connectIds(billIdSet);

        // 获取所有分单对象
        List<BNativeBillPojo> nativeBillPojoList = bNativeBillService.getBNativeBillPojoListByInId(billIds);

        if (nativeBillPojoList.isEmpty()) {
            throw new Exception("获取分单配载信息为空，主单成本分摊操作失败!");
        }

        // 分单 List 转 Map 方便进行后续的查找操作
        Map<String, BNativeBillPojo> nativeBillPojoMap = new HashMap<>();
        for (BNativeBillPojo pojo : nativeBillPojoList) {
            nativeBillPojoMap.put(pojo.getId(), pojo);
        }

        // 4.开始进行分摊操作
        for (BMasterBillFlightPojo masterBillPojo : masterBillFlightPojoList) {
            // 4.1 根据主单号获取配载表中所有分单配置信息
            List<BNativeBillLoadPojo> tempBillLoadList = new ArrayList<>();
            for (BNativeBillLoadPojo loadPojo : nativeBillLoadPojoList) {
                if (masterBillPojo.getId().equals(loadPojo.getMasterBillId())) {
                    tempBillLoadList.add(loadPojo);
                }
            }
            // 为如果为 null,则不进行分摊，进入下一个主单号进行分摊
            if (tempBillLoadList.isEmpty()) {
                continue;
            }

            // 当前的tempBillLoadList有统一主单号,为什么会出现这种情况，是有可能会出合大票或拉货改配时的情况，出现一个主单号下面有多个分单号的情况
            for (BNativeBillLoadPojo billLoadPojo : tempBillLoadList) {
                // 分单号
                String bNativeBillCode = billLoadPojo.getNativeBillId();
                // 这个地方要注意选择分单的（这个地方有问题）
                BNativeBillPojo billPojo = nativeBillPojoMap.get(bNativeBillCode);

                // 如果获取的分单对象为 null, 则不会进行分摊，进入下一个环节
                if (billPojo == null) {
                    continue;
                }

                // 下面检测分单的配载状态，必须是全部实配才可以进行成本分摊,
                // 同时要注意是什么样的配载方式，如果是合大票，则需要找出相应所有的主单


                // 分单已经配载重量占主单计费重量百分比(此时的分单配载的分单号与 分单对象是同一个分单号)
                // 分单已经配载重量占主单计费重量百分比 = 分单配载的计费重量 / 配载主单的总的计费重量
                Double weightSharePercentage = DoubleUtil.div(billLoadPojo.getLoadChargeableWeight(), masterBillPojo.getChargeableWeight(), 2);
                // 分摊成本 = 配载主单的结算费用 * 分单已经配载重量占主单计费重量百分比
                Double shareCost = DoubleUtil.mul(masterBillPojo.getSettlementAmount(), weightSharePercentage, 2);


                // 写入对应的主单成本是如何分摊在分单上的信息
                Map<String, Object> shareCostCommentMap = new HashMap<>();
                shareCostCommentMap.put("主单号", masterBillPojo.getId());
                shareCostCommentMap.put("主单重量费率", masterBillPojo.getWeightRate());
                shareCostCommentMap.put("主单结算金额", masterBillPojo.getSettlementAmount());
                shareCostCommentMap.put("主单航空运费", masterBillPojo.getTransportCost());
                shareCostCommentMap.put("主单总金额", masterBillPojo.getTotalAmount());
                shareCostCommentMap.put("主单航空附加", masterBillPojo.getAirlinesAddCost());
                shareCostCommentMap.put("主单地面运费", masterBillPojo.getGroundAmount());
                shareCostCommentMap.put("分单号", billPojo.getId());
                shareCostCommentMap.put("分摊成本", shareCost);
                String shareCostComment = JSONObject.toJSONString(shareCostCommentMap);

                // 需要注意的是要检测这个分单是否被配载到多个主单上，如果是，则不不能清空，但是会有问题的
                // 回写到原来的分单上,需要注意的是原来的成本可能不为0，则取出来后相加
                Double billOriginalShareCost = billPojo.getShareCost();
                billPojo.setShareCost(DoubleUtil.sum(billOriginalShareCost, shareCost, 2));

                String billPojoShareCostComment = billPojo.getShareCostComment();
                if (billPojoShareCostComment == null) {
                    billPojo.setShareCostComment(shareCostComment);
                } else {
                    billPojo.setShareCostComment(billPojoShareCostComment + "," + shareCostComment);
                }

                // 同时把分单的利润也算出来
                // 分单利润=分单结算金额(settlement_amount) - 业务费(service_charge) - 代理送货费(agent_delivery_charge) - 分单分摊成本(share_cost)-锦添操作费(operating_cost这个操作费还没有定，要给出解决方案,现在不考虑)
                // grossProfit
                Double billSettlementAmount = billPojo.getSettlementAmount();
                Double billServiceCharge = billPojo.getServiceCharge();
                Double billAgentDeliveryCharge = billPojo.getAgentDeliveryCharge();
                Double billShareCost = billPojo.getShareCost();
                Double billOperatingCost = billPojo.getOperatingCost();

                Double billGrossProfit = DoubleUtil.div(billSettlementAmount, (billServiceCharge + billAgentDeliveryCharge + billShareCost + billOperatingCost), 2);

                // 填写当前利润额
                billPojo.setGrossProfit(billGrossProfit);

            }

        }

        // 下面对map 中的所有对象进行更新操作(回写入数据库)
        int affectRows = 0;
        for (Map.Entry<String, BNativeBillPojo> entry : nativeBillPojoMap.entrySet()) {
            affectRows += SpringAopUtil.getBean(BNativeBillService.class).update(entry.getValue());
        }
        return affectRows;
    }

    private String connectIds(Collection<String> collection) throws Exception {
        StringBuffer strBuffer = new StringBuffer("");
        for (String id : collection) {
            strBuffer.append(DataTypeUtil.quoteStr(id)).append(",");
        }

        if (strBuffer.length() == 0) {
            throwException("ID连接失败!");
        }

        String ids = strBuffer.substring(0, strBuffer.length() - 1);
        return ids;
    }

    /**
     * 根据主单号获取分单列表对象
     *
     * @param masterBillId
     * @return
     */
    public List<BNativeBillPojo> queryBNativeBillPojoListByMasterBillId(String masterBillId) throws Exception {
        if (DataTypeUtil.isEmptyStr(masterBillId)) {
            throwException("主单号查询分单列表参数错误!");
        }

        List<BNativeBillPojo> bNativeBillPojoList = bNativeBillService.queryBNativeBillPojoListByMasterBillId(masterBillId);

        return bNativeBillPojoList;
    }


    /**
     * 无拉货状态检测删除主单
     * @param param
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int noPullStatusCheckDeleteMasterBillByMasterBillIds(Map param) throws Exception {
        if (param == null || param.isEmpty()) {
            throwException("主单删除参数错误!");
        }

        String masterBillIds = DataTypeUtil.toStringObject(param.get("masterBillIds"));
        if (masterBillIds == null || masterBillIds.isEmpty()) {
            throwException("主单删除参数错误!");
        }
        // 返回的影响行数，记录主单被删除的行数
        int affectRows = SysConstant.INT_ZERO;

        String czyId = this.getLoginCzyId();
        Date currentTime = this.getSysTime();

        // 分离主单号为数组
        String[] masterBillIdArray = masterBillIds.split(",");

        for (String masterBillId : masterBillIdArray) {
            // 1.加载主单对象
            BMasterBillFlightPojo bMasterBillFlightPojo = getBMasterBillFlightPojoById(masterBillId);
            if (bMasterBillFlightPojo == null) {
                throwException("加载【" + masterBillId + "】主单对象失败!");
            }

            // 2.加载主单现有配载对象
            List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListByMasterBillId(masterBillId);


            // 3.判断是否加载到对应的分单配载列表
            if (bNativeBillLoadPojoList == null) {
                throwException("加载【" + masterBillId + "】主单配载列表对象失败!");
            }

            // 4.有两种可能，一种是全拉后没有配载信息,一种是有配载信息
            if (!bNativeBillLoadPojoList.isEmpty()) {
                // 4.这是有配载对象，注意可能补发，所以需要遍历，把同一个分单的件数给累加起来放到 map 中
                Map<String, Long> nativeLoadTotalNumberMap = new HashMap<>();
                for (BNativeBillLoadPojo bNativeBillLoadPojo : bNativeBillLoadPojoList) {
                    // 这是对应masterBillId主单号下的配载分单号
                    String nativeBillId = bNativeBillLoadPojo.getNativeBillId();
                    // 这是对应masterBillId主单号下nativeBillId分单的配载件数
                    Long loadNumber = bNativeBillLoadPojo.getLoadNumber();

                    if (nativeLoadTotalNumberMap.containsKey(nativeBillId)) {
                        Long number = nativeLoadTotalNumberMap.get(nativeBillId);
                        nativeLoadTotalNumberMap.put(nativeBillId, loadNumber + number);
                    } else {
                        nativeLoadTotalNumberMap.put(nativeBillId, loadNumber);
                    }
                }

                // 遍历 nativeLoadTotalNumberMap,与原始分单中的件数进行对比
                for (String nativeBillId : nativeLoadTotalNumberMap.keySet()) {
                    // 获取分单原始对象
                    BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(nativeBillId);
                    // 分单原始配载件数
                    Integer totalNumber = bNativeBillPojo.getTotalNumber();
                    // 配载表中的总件数
                    Long totalLoadNumber = nativeLoadTotalNumberMap.get(nativeBillId);

                    // 判断件数是否相等
                    if (totalLoadNumber.intValue() == totalNumber.intValue()) {
                        // 件数相等，则可以恢复期对应的原始信息,需要清空其拉货状态，分单退货件数等等信息，
                        // 恢复分单原始信息
                        restoreNativeBill(SysConstant.ZERO,
                                SysConstant.XT_DIC_PULL_STATUS.NO_PULL.getId(),
                                SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId(),
                                SysConstant.INT_ZERO,
                                SysConstant.ZERO,
                                SysConstant.ZERO,
                                SysConstant.ZERO,
                                czyId, currentTime, bNativeBillPojo);

                    } else {
                        // 不相等，说明totalLoadNumber(配载表中的件数之和)肯定小于totalNumber(原始分单件数),因为totalNumber肯定不会比totalLoadNumber小
                        // 1.检测这个分单除了这个主单配载，是否还有其他配载情况
                        Map<String, Object> queryParam = new HashMap<>();
                        // 排除当前的主单号
                        queryParam.put("excludeMasterBillIds", masterBillId);
                        // 这是分单号
                        queryParam.put("billId", nativeBillId);

                        // 得到nativeBillId分单在masterBillId主单号之外的配载信息列表
                        List<BNativeBillLoadPojo> loadPojoList = bNativeBillLoadService.queryNativeBillListNoPage(queryParam);

                        // 如果该分单没有被配载到其他主单号，则直接恢复到原始状态
                        if (loadPojoList == null || loadPojoList.isEmpty()) {
                            // 按原来的进行处理
                            /**
                             * Double dropAmount, Long dropStatusId, Long billLoadStatusId,
                             *  Integer refundNumber, Double refundActualWeight, Double refundChargeableWeight, Double refundVolume,
                             *  String czyId, Date currentTime, BNativeBillPojo bNativeBillPojo
                             */
                            restoreNativeBill(SysConstant.ZERO,
                                    SysConstant.XT_DIC_PULL_STATUS.NO_PULL.getId(),
                                    SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId(),
                                    SysConstant.INT_ZERO,
                                    SysConstant.ZERO,
                                    SysConstant.ZERO,
                                    SysConstant.ZERO,
                                    czyId, currentTime, bNativeBillPojo);
                        } else {
                            // 注意这里的 nativeBillId 肯定只有一个,因为前面查询的时候给了 nativeBillId 的条件
                            // 这是处置方式为 补发或改配时的拉货 map
                            Map<String, Long> pullNumberMap = new HashMap<>();
                            Map<String, Double> pullActualWeightMap = new HashMap<>();
                            Map<String, Double> pullChargeableWeightMap = new HashMap<>();
                            Map<String, Double> pullVolumeMap = new HashMap<>();
                            Map<String, Double> pullAmountMap = new HashMap<>();

                            // 这是处置方式为 退货时的拉货 map
                            Map<String, Long> pullRefundNumberMap = new HashMap<>();
                            Map<String, Double> pullRefundActualWeightMap = new HashMap<>();
                            Map<String, Double> pullRefundChargeableWeightMap = new HashMap<>();
                            Map<String, Double> pullRefundVolumeMap = new HashMap<>();
                            Map<String, Double> pullRefundAmountMap = new HashMap<>();

                            // 不是空有内容，说明这个分单被分开配载了
                            // 遍历loadPojoList找一下分开配载的主单是否有拉货相关信息
                            for (BNativeBillLoadPojo loadPojo : loadPojoList) {
                                // 取出主单号
                                String tempMasterBillId = loadPojo.getMasterBillId();
                                // 取出主单类型
                                Long tempMasterBillTypeId = loadPojo.getMasterBillTypeId();
                                // 根据这个主单号与主单类型查一下是否有对应的拉货信息
                                BMasterBillPullPojo bMasterBillPullPojo = bMasterBillPullService.getBMasterBillPullPojoByMasterBillIdAndBillTypeId(tempMasterBillId, tempMasterBillTypeId);
                                if (bMasterBillPullPojo != null) {
                                    String masterBillPullId = bMasterBillPullPojo.getId();
                                    Map<String, Object> pullDetailQueryParam = new HashMap<>();
                                    pullDetailQueryParam.put("masterBillPullId", masterBillPullId);
                                    pullDetailQueryParam.put("nativeBillId", nativeBillId);
                                    // 获取拉货信息
                                    List<BMasterBillPullDetailPojo> pullDetailPojoList = bMasterBillPullDetailService.queryPullDetailListNoPage(pullDetailQueryParam);

                                    if (pullDetailPojoList != null && !pullDetailPojoList.isEmpty()) {
                                        for (BMasterBillPullDetailPojo pullDetailPojo : pullDetailPojoList) {
                                            // 这是退客户的处置方式
                                            if (pullDetailPojo.getPullDisposeId().longValue() == SysConstant.XT_DIC_NATIVE_PULL_DISPOSE.REFUND.getId()) {
                                                if (pullRefundNumberMap.containsKey(nativeBillId)) {
                                                    pullRefundNumberMap.put(nativeBillId, pullRefundNumberMap.get(nativeBillId) + pullDetailPojo.getPullNumber());
                                                    pullRefundActualWeightMap.put(nativeBillId, DoubleUtil.sum(pullRefundActualWeightMap.get(nativeBillId), pullDetailPojo.getPullActualWeight(), 2));
                                                    pullRefundChargeableWeightMap.put(nativeBillId, DoubleUtil.sum(pullRefundChargeableWeightMap.get(nativeBillId), pullDetailPojo.getPullChargeableWeight(), 2));
                                                    pullRefundVolumeMap.put(nativeBillId, DoubleUtil.sum(pullRefundVolumeMap.get(nativeBillId), pullDetailPojo.getPullVolume(), 2));
                                                    pullRefundAmountMap.put(nativeBillId, DoubleUtil.sum(pullRefundAmountMap.get(nativeBillId), pullDetailPojo.getPullAmount(), 2));
                                                } else {
                                                    pullRefundNumberMap.put(nativeBillId, pullDetailPojo.getPullNumber());
                                                    pullRefundActualWeightMap.put(nativeBillId, pullDetailPojo.getPullActualWeight());
                                                    pullRefundChargeableWeightMap.put(nativeBillId, pullDetailPojo.getPullChargeableWeight());
                                                    pullRefundVolumeMap.put(nativeBillId, pullDetailPojo.getPullVolume());
                                                    pullRefundAmountMap.put(nativeBillId, pullDetailPojo.getPullAmount());
                                                }
                                            } else {
                                                // 这是补发或改配的处置方式
                                                if (pullNumberMap.containsKey(nativeBillId)) {
                                                    pullNumberMap.put(nativeBillId, pullNumberMap.get(nativeBillId) + pullDetailPojo.getPullNumber());
                                                    pullActualWeightMap.put(nativeBillId, DoubleUtil.sum(pullActualWeightMap.get(nativeBillId), pullDetailPojo.getPullActualWeight(), 2));
                                                    pullChargeableWeightMap.put(nativeBillId, DoubleUtil.sum(pullChargeableWeightMap.get(nativeBillId), pullDetailPojo.getPullChargeableWeight(), 2));
                                                    pullVolumeMap.put(nativeBillId, DoubleUtil.sum(pullVolumeMap.get(nativeBillId), pullDetailPojo.getPullVolume(), 2));
                                                    pullAmountMap.put(nativeBillId, DoubleUtil.sum(pullAmountMap.get(nativeBillId), pullDetailPojo.getPullAmount(), 2));
                                                } else {
                                                    pullNumberMap.put(nativeBillId, pullDetailPojo.getPullNumber());
                                                    pullActualWeightMap.put(nativeBillId, pullDetailPojo.getPullActualWeight());
                                                    pullChargeableWeightMap.put(nativeBillId, pullDetailPojo.getPullChargeableWeight());
                                                    pullVolumeMap.put(nativeBillId, pullDetailPojo.getPullVolume());
                                                    pullAmountMap.put(nativeBillId, pullDetailPojo.getPullAmount());
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            // 到此该分单所有拉货件数与拉货实重、拉货计重、拉货体积、拉货调整金额全部放在到了对应的 map 中，且为分单id 为 key
                            if (pullNumberMap.containsKey(nativeBillId) || pullRefundNumberMap.containsKey(nativeBillId)) {
                                //  补发与改配拉货总件
                                Long pullNumber = 0L;
                                Double pullActualWeight = 0D;
                                Double pullChargeableWeight = 0D;
                                Double pullVolume = 0D;
                                Double pullAmount = 0D;

                                if (pullNumberMap.containsKey(nativeBillId)) {
                                    pullNumber = pullNumberMap.get(nativeBillId);
                                    pullActualWeight = pullActualWeightMap.get(nativeBillId);
                                    pullChargeableWeight = pullChargeableWeightMap.get(nativeBillId);
                                    pullVolume = pullVolumeMap.get(nativeBillId);
                                    pullAmount = pullAmountMap.get(nativeBillId);
                                }

                                Long pullRefundNumber = 0L;
                                Double pullRefundActualWeight = 0D;
                                Double pullRefundChargeableWeight = 0D;
                                Double pullRefundVolume = 0D;
                                Double pullRefundAmount = 0D;

                                if (pullRefundNumberMap.containsKey(nativeBillId)) {
                                    pullRefundNumber = pullRefundNumberMap.get(nativeBillId);
                                    pullRefundActualWeight = pullRefundActualWeightMap.get(nativeBillId);
                                    pullRefundChargeableWeight = pullRefundChargeableWeightMap.get(nativeBillId);
                                    pullRefundVolume = pullRefundVolumeMap.get(nativeBillId);
                                    pullRefundAmount = pullRefundAmountMap.get(nativeBillId);
                                }

                                restoreNativeBill(DoubleUtil.round2(pullAmount + pullRefundAmount), SysConstant.XT_DIC_PULL_STATUS.PULL.getId(), SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId(),
                                        pullRefundNumber.intValue(), DoubleUtil.round2(pullRefundActualWeight), DoubleUtil.round2(pullRefundChargeableWeight), DoubleUtil.round2(pullRefundVolume),
                                        czyId, currentTime, bNativeBillPojo);
                            } else {
                                // 这是恢复原始信息
                                restoreNativeBill(SysConstant.ZERO,
                                        SysConstant.XT_DIC_PULL_STATUS.NO_PULL.getId(),
                                        SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId(),
                                        SysConstant.INT_ZERO,
                                        SysConstant.ZERO,
                                        SysConstant.ZERO,
                                        SysConstant.ZERO,
                                        czyId, currentTime, bNativeBillPojo);
                            }
                        }
                        // 不相等
                    }
                    // 到此这个主单下的所有分单调整完成
                }
            }

            // 到此就可以根据主单号删除相应的分摊成本，主单配载信息，主单信息，就可以了
            // 1.删除b_native_bill_pull_cost 根据主单号
            int pullCostDeleteAffectRows = bNativeBillPullCostService.deleteByMasterBillId(masterBillId);

            // 2.删除拉货明细b_master_bill_pull_detail 根据主单号
            int pullDetailDeleteAffectRows = bMasterBillPullDetailService.deleteByMasterBillId(masterBillId);

            // 3.删除b_master_bill_pull根据主单号
            int pullDeleteAffectRows = bMasterBillPullService.deleteByMasterBillId(masterBillId);

            // 4.删除主单的配载信息
            int billLoadDeleteAffectRows = bNativeBillLoadService.deleteLoadNativeBillByMasterBillId(masterBillId);

            // 5.恢复主单号的使用状态
            BMasterBillCodePojo bMasterBillCodePojo = bMasterBillCodeService.fetch(masterBillId);
            if (bMasterBillCodePojo != null) {
                bMasterBillCodePojo.setUseStatusId(SysConstant.XT_DIC_USE_STATUS.UNUSED.getId());
                bMasterBillCodePojo.setUseDepartmentId(null);
                bMasterBillCodePojo.setUseUserId(null);
                int updateMasterBillCodeAffectRows = bMasterBillCodeService.update(bMasterBillCodePojo);
            }

            // 6.删除对应的主单
            affectRows += bMasterBillFlightMapper.delete(masterBillId);
        }
        // 返回受影响的行数
        return affectRows;
    }


    // 恢复分单原始信息，这个方法要调整到分单业务类中，汽运时也会有可能使用
    private void restoreNativeBill(Double dropAmount, Long dropStatusId, Long billLoadStatusId,
                                   Integer refundNumber, Double refundActualWeight, Double refundChargeableWeight, Double refundVolume,
                                   String czyId, Date currentTime, BNativeBillPojo bNativeBillPojo) throws Exception {
        // 1.拉货状态修改为全部未拉货
        bNativeBillPojo.setDropAmount(dropAmount);
        bNativeBillPojo.setDropStatusId(dropStatusId);

        // 2.分单结算金额调整为实收金额+拉货调整金额
        bNativeBillPojo.setSettlementAmount(DoubleUtil.sum(bNativeBillPojo.getActualAmount(), bNativeBillPojo.getDropAmount(), 2));
        bNativeBillPojo.setSettlementStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.UNCLEARED.getId());

        // 3.分单对账状态恢复为未对账
        bNativeBillPojo.setAccountCheckStatusId(SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId());

        // 4.分单利润调整为0  分单成本调整为0  分单成本说明清空
        bNativeBillPojo.setGrossProfit(SysConstant.ZERO);
        bNativeBillPojo.setShareCost(SysConstant.ZERO);
        bNativeBillPojo.setShareCostComment("");

        // 5.设置配载状态,配载主单号清空
        bNativeBillPojo.setBillLoadStatusId(billLoadStatusId);
        bNativeBillPojo.setBillLoadMasterBillIds("");

        // 6.分单拉货退客户件数信息按传入参数进行调整
        bNativeBillPojo.setRefundNumber(refundNumber);
        bNativeBillPojo.setRefundActualWeight(refundActualWeight);
        bNativeBillPojo.setRefundChargeableWeight(refundChargeableWeight);
        bNativeBillPojo.setRefundVolume(refundVolume);

        // 7.填写更新人信息
        bNativeBillPojo.setUpdateTime(currentTime);
        bNativeBillPojo.setUpdateUserId(czyId);

        // 8.可以更新分单信息了
        bNativeBillService.update(bNativeBillPojo);
    }


    /**
     * 根据主单号删除主单
     *
     * @param param
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int deleteMasterBillByMasterBillIds(Map param) throws Exception {
        if (param == null || param.isEmpty()) {
            throwException("主单删除参数错误!");
        }
        String masterBillIds = DataTypeUtil.toStringObject(param.get("masterBillIds"));
        if (masterBillIds == null || masterBillIds.isEmpty()) {
            throwException("主单删除参数错误!");
        }
        // 返回的影响行数，记录主单被删除的行数
        int affectRows = 0;

        /**
         * 主单删除逻辑
         1.主单删除时如果主单的对账状态是 已对账，已拉货 则不能删除
         2.如果是自发的主单号会被回收，供再次使用
         3.主单删除时其下的相关配载信息会一并删除
         5.分单不会删除，但会修改其配载状态为未配载或部分配载，原分单成本及分单利润会调整为0  drop_status_id
         */
        // 分离主单号为数组
        String[] masterBillIdArray = masterBillIds.split(",");
        // 遍历等待删除的主单号
        for (String masterBillId : masterBillIdArray) {
            // 1.根据主单号加载主单对象
            BMasterBillFlightPojo bMasterBillFlightPojo = getBMasterBillFlightPojoById(masterBillId);
            if (bMasterBillFlightPojo == null) {
                throwException("待删除的主单【" + masterBillId + "】对象不存在，删除主单失败!");
            }

            // 2.检测主单状态
            if (bMasterBillFlightPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                    || bMasterBillFlightPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    || bMasterBillFlightPojo.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
                throw new Exception("待删除的主单【" + masterBillId + "】对象 已拉货、已对账或已结算，删除主单失败!");
            }

            // 3.根据主单ID 加载主单下的配载列表
            List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListByMasterBillId(masterBillId);
            if (bNativeBillLoadPojoList == null || bNativeBillLoadPojoList.isEmpty()) {
                throwException("待删除的主单【" + masterBillId + "】对象 配载分单为空，删除主单失败!");
            }

            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                String nativeBillId = loadPojo.getNativeBillId();
                // 检测配载列表中的分单是否做过拉货或对账或结算状态
                BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(nativeBillId);
                // 检测分单对象是否存在
                if (bNativeBillPojo == null) {
                    throwException("待删除的主单【" + masterBillId + "】对象下的配载分单【" + nativeBillId + "】对象在分单表中不存在，删除主单失败!");
                }
                // 检测分单对象是否做过拉货、对过账、结算过
                if (bNativeBillPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                        || bNativeBillPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                        || bNativeBillPojo.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
                    throwException("待删除的主单【" + masterBillId + "】下的配置分单【" + nativeBillId + "】对象 已拉货、已对账或已结算，删除主单失败!");
                }

                // 调用删除，把该配载信息给删除
                int deleteBillLoadAffectRows = bNativeBillLoadService.delete(loadPojo.getId());
            }

            // 到此该主单下的所有配载信息删除完成,下面根据已经删除的配载信息做遍历更新原始分单相应的配载状态,因为可能一分单被配载到多个主单，但我们只删除了一个主单
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                String nativeBillId = loadPojo.getNativeBillId();
                Map<String, Object> cndParam = new HashMap<>();
                cndParam.put("billId", nativeBillId);
                List<BNativeBillLoadPojo> billLoadPojoList = bNativeBillLoadService.queryNativeBillListNoPage(cndParam);

                // 定义默认总配载件数
                long totalLoadNumber = 0;
                // 定义还剩余的配载主单号
                Set<String> billLoadMasterBillSet = new HashSet<>();
                if (billLoadPojoList != null && !billLoadPojoList.isEmpty()) {
                    for (BNativeBillLoadPojo pojo : billLoadPojoList) {
                        totalLoadNumber += pojo.getLoadNumber();
                        billLoadMasterBillSet.add(pojo.getMasterBillId());
                    }
                }
                String billLoadMasterBillIds = "";
                if (!billLoadMasterBillSet.isEmpty()) {
                    for (String masterId : billLoadMasterBillSet) {
                        billLoadMasterBillIds += masterId + ",";
                    }
                }

                if (billLoadMasterBillIds.length() > 0) {
                    billLoadMasterBillIds.substring(0, billLoadMasterBillIds.length() - 1);
                }

                // 获取原始分单对象
                BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(nativeBillId);

                bNativeBillPojo.setBillLoadMasterBillIds(billLoadMasterBillIds);
                bNativeBillPojo.setShareCost(0D);
                bNativeBillPojo.setGrossProfit(0D);
                bNativeBillPojo.setShareCostComment("");


                if (totalLoadNumber == 0) {
                    bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId());
                } else {
                    bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId());
                }

                // 更新分单对象
                int updateNativeBillAffectRows = bNativeBillService.update(bNativeBillPojo);
            }

            // 下面删除主的其他费用
            int deleteMasterBillOtherChargeAffectRows = bMasterBillOtherChargeService.deleteByMasterBillId(masterBillId);

            // 因为是航空主单 所以释放删除的主单号供再次使用
            if (bMasterBillFlightPojo.getTransportWayId().longValue() == SysConstant.XT_DIC_TRANSPORT_WAY.SELF.getId()) {
                bMasterBillCodeService.updateUseStatus(masterBillId, SysConstant.XT_DIC_USE_STATUS.UNUSED.getId(), null, null);
            }

            // 最后删除主单对象
            affectRows += this.delete(masterBillId);
        }

        return affectRows;
    }

    @Transactional(rollbackFor = {Exception.class})
    public int delete(String id) throws Exception {
        if (DataTypeUtil.isEmptyStr(id)) {
            throwException("删除航空主单ID参数错误!");
        }
        return bMasterBillFlightMapper.delete(id);
    }

    public List<Map<String, Object>> queryFlightAirlinesOpenBillCollectList(String startDate, String endDate) {
        return bMasterBillFlightMapper.queryFlightAirlinesOpenBillCollectList(startDate, endDate);
    }

    public List<Map<String, Object>> queryFlightAirportOpenBillCollectList(String startDate, String endDate) {
        return bMasterBillFlightMapper.queryFlightAirportOpenBillCollectList(startDate, endDate);
    }


    /**
     * 上传并处理对账信息
     *
     * @param upLoadFile
     * @param accountFileType
     * @return
     */
    public String accountFileUploadAndCheck(MultipartFile upLoadFile, Long accountFileType) throws Exception {
        // 1.上传文件
        XtUploadFilePojo filePojo = xtUploadFileService.upload(upLoadFile);

        // 2.处理对账
        String reulstMsg = processMasterBillAccount(filePojo, accountFileType);

        return reulstMsg;
    }



    static class ExcelObj{
        public Workbook wb;
        public Sheet sheet;
    }

    static class ListMapAndException{
        public List<Map<String, Object>> listMap;
        public StringBuffer exceptionInfoStr;
    }

    // 返回 Excel Sheet
    private ExcelObj getExcelObject(XtUploadFilePojo filePojo) throws Exception {
        File destFile = xtUploadFileService.getFile(filePojo);

        // 定义读取文件的输入流
        FileInputStream fis = new FileInputStream(destFile);

        Workbook wb = PoiUtil.getWorkBook(destFile, fis);

        Sheet sheet = wb.getSheetAt(0);

        ExcelObj excelObj = new ExcelObj();
        excelObj.wb = wb;
        excelObj.sheet = sheet;

        return excelObj;
    }

    private ListMapAndException getConvertExcelToListMap(ExcelObj excelObj) throws Exception {
        Sheet sheet = excelObj.sheet;
        Workbook wb = excelObj.wb;
        int rows = sheet.getLastRowNum();

        if (rows < 2) {
            throw new Exception("Excel文件内容为空");
        }

        // 1.按行读取所有Excel中的每一行，形成一个List<Map>
        List<Map<String, Object>> listMap = new ArrayList<>();
        // 异常处理字符串
        StringBuffer exceptionInfoStr = new StringBuffer();

        for (int i = 1; i <= rows; i++) {
            Row row = sheet.getRow(i);
            int rowNum = row.getRowNum() + 1;
            if (row != null) {
                boolean flag = true;
                Map<String, Object> map = new HashMap<>();

                // 主单号(0)
                String masterBillId = PoiUtil.getExcelCellValue(wb, row, 0);
                if (DataTypeUtil.isEmptyStr(masterBillId)) {
                    flag = false;
                    exceptionInfoStr.append("上传的excel文件中的【" + rowNum + "】行【主单号】为空<br/>");
                }


                // 金额(2)
                Double amount = DataTypeUtil.toDouble(PoiUtil.getExcelCellValue(wb, row, 1), DEFAULT_AMOUNT, 2);
                if (amount.doubleValue() == DEFAULT_AMOUNT.doubleValue()) {
                    flag = false;
                    exceptionInfoStr.append("上传的excel文件中的【" + rowNum + "】行【金额】为空<br/>");
                }


                if (flag) {
                    map.put("masterBillId", masterBillId);
                    map.put("amount", amount);
                    listMap.add(map);
                }
            }
        }

        ListMapAndException listMapAndException = new ListMapAndException();
        listMapAndException.listMap = listMap;
        listMapAndException.exceptionInfoStr = exceptionInfoStr;

        return listMapAndException;
    }


    @Transactional(rollbackFor = {Exception.class})
    public String processMasterBillAccount(XtUploadFilePojo filePojo, Long accountFileType) throws Exception {

        ExcelObj excelObj = getExcelObject(filePojo);

        ListMapAndException listMapAndException = getConvertExcelToListMap(excelObj);

        // 1.按行读取所有Excel中的每一行，形成一个List<Map>
        List<Map<String, Object>> listMap = listMapAndException.listMap;
        // 异常处理字符串
        StringBuffer exceptionInfoStr = listMapAndException.exceptionInfoStr;

        if (exceptionInfoStr.length() > SysConstant.INT_ZERO) {
            throwException(exceptionInfoStr.toString());
        }

        // 迭代处理
        StringBuilder masterBillIds = new StringBuilder();
        for (Map<String, Object> map : listMap) {
            String masterBillId = DataTypeUtil.toNotNullString(map.get("masterBillId"));
            Double amount = DataTypeUtil.toDouble(map.get("amount"), DEFAULT_AMOUNT, 2);

            BMasterBillFlightPojo flightPojo = getBMasterBillFlightPojoById(masterBillId);

            if (flightPojo == null) {
                exceptionInfoStr.append("【" + masterBillId + "】主单对象不存在<br/>");
                continue;
            }

            if (accountFileType.longValue() == SysConstant.TRANSPORT_COST_ACCOUNT_FILE_TYPE.longValue()) {
                //  这是对账航空运费
                Double transportCost = DataTypeUtil.toDouble(flightPojo.getTransportCost(), SysConstant.ZERO, 2);
                Double pullDisposeTransportCostAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeTransportCostAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(transportCost, pullDisposeTransportCostAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应航空运费结算金额【" + amount + "】与系统中的对应主单航空运费结算金额【" + transportCost + "+" + pullDisposeTransportCostAmount + "】不一致<br/>");
                }
            } else if (accountFileType.longValue() == SysConstant.GROUND_AMOUNT_ACCOUNT_FILE_TYPE.longValue()) {
                // 这是对账地面运费
                Double groundAmount = DataTypeUtil.toDouble(flightPojo.getGroundAmount(), SysConstant.ZERO, 2);
                Double pullDisposeGroundAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeGroundAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(groundAmount, pullDisposeGroundAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应地面运费结算金额【" + amount + "】与系统中的对应主单地面运费结算金额【" + groundAmount + "+" + pullDisposeGroundAmount + "】不一致<br/>");
                }
            } else if (accountFileType.longValue() == SysConstant.AIRLINES_ADD_COST_ACCOUNT_FILE_TYPE.longValue()) {
                // 这是对账燃油附加费
                Double airlinesAddCost = DataTypeUtil.toDouble(flightPojo.getAirlinesAddCost(), SysConstant.ZERO, 2);
                Double pullDisposeAirlinesAddCostAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeAirlinesAddCostAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(airlinesAddCost, pullDisposeAirlinesAddCostAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应航空燃油附加费结算金额【" + amount + "】与系统中的对应主单航空燃油附加费结算金额【" + airlinesAddCost + "+" + pullDisposeAirlinesAddCostAmount + "】不一致<br/>");
                }
            } else if (accountFileType.longValue() == SysConstant.OTHER_CHARGES_ACCOUNT_FILE_TYPE.longValue()) {
                // 这是对账其他费用
                Double otherCharges = DataTypeUtil.toDouble(flightPojo.getOtherCharges(), SysConstant.ZERO, 2);
                Double pullDisposeOtherChargesAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeOtherChargesAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(otherCharges, pullDisposeOtherChargesAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应其他费用结算金额【" + amount + "】与系统中的对应主单其他费用结算金额【" + otherCharges + "+" + pullDisposeOtherChargesAmount + "】不一致<br/>");
                }
            }
        }

        if (masterBillIds.length() > SysConstant.INT_ZERO) {
            String updateMasterBillIds = masterBillIds.substring(0, masterBillIds.length() - 1);

            String statusFieldName = "";

            if (accountFileType.longValue() == SysConstant.TRANSPORT_COST_ACCOUNT_FILE_TYPE.longValue()) {
                statusFieldName = "transport_cost_account_check_status_id";
            } else if (accountFileType.longValue() == SysConstant.GROUND_AMOUNT_ACCOUNT_FILE_TYPE.longValue()) {
                statusFieldName = "ground_amount_account_check_status_id";
            } else if (accountFileType.longValue() == SysConstant.AIRLINES_ADD_COST_ACCOUNT_FILE_TYPE.longValue()) {
                statusFieldName = "airlines_add_cost_account_check_status_id";
            } else if (accountFileType.longValue() == SysConstant.OTHER_CHARGES_ACCOUNT_FILE_TYPE.longValue()) {
                statusFieldName = "other_charges_account_check_status_id";
            }

            // 执行更新操作
            if (!DataTypeUtil.isEmptyStr(statusFieldName)) {
                updateStatusId(statusFieldName, SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId(), updateMasterBillIds);
            }

            // 这个地方再检测对象的所有对账状态，以确保整个对象的全局对账状态
            List<BMasterBillFlightPojo> bMasterBillFlightPojoList = this.bMasterBillFlightMapper.getBMasterBillFlightPojoListByInId(updateMasterBillIds);

            String tempIds = "";
            for (BMasterBillFlightPojo pojo : bMasterBillFlightPojoList) {
                Long transportCostAccountCheckStatusId = DataTypeUtil.toLong(pojo.getTransportCostAccountCheckStatusId(),-1);
                Long groundAmountAccountCheckStatusId = DataTypeUtil.toLong(pojo.getGroundAmountAccountCheckStatusId(),-1);
                Long airlinesAddCostAccountCheckStatusId = DataTypeUtil.toLong(pojo.getAirlinesAddCostAccountCheckStatusId(),-1);
                Long otherChargesAccountCheckStatusId = DataTypeUtil.toLong(pojo.getOtherChargesAccountCheckStatusId(),-1);
                if (transportCostAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                        && groundAmountAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                        && airlinesAddCostAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                        && otherChargesAccountCheckStatusId == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                ) {
                    tempIds = "'" + pojo.getId() + "',";
                }
            }
            if (tempIds.length() > 0) {
                tempIds = tempIds.substring(0, tempIds.length() - 1);
                updateStatusId("account_check_status_id", SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId(), tempIds);
            }
        }

        return exceptionInfoStr.toString();
    }

    public String settlementFileUploadAndCheck(MultipartFile upLoadFile, Long settlementFileType) throws Exception {
        // 1.上传文件
        XtUploadFilePojo filePojo = xtUploadFileService.upload(upLoadFile);

        // 2.处理对账
        String reulstMsg = processMasterBillSettlement(filePojo, settlementFileType);

        return reulstMsg;
    }

    @Transactional(rollbackFor = {Exception.class})
    public String processMasterBillSettlement(XtUploadFilePojo filePojo, Long settlementFileType) throws Exception {

        ExcelObj excelObj = getExcelObject(filePojo);

        ListMapAndException listMapAndException = getConvertExcelToListMap(excelObj);

        // 1.按行读取所有Excel中的每一行，形成一个List<Map>
        List<Map<String, Object>> listMap = listMapAndException.listMap;
        // 异常处理字符串
        StringBuffer exceptionInfoStr = listMapAndException.exceptionInfoStr;

        if (exceptionInfoStr.length() > SysConstant.INT_ZERO) {
            throwException(exceptionInfoStr.toString());
        }

        // 迭代处理
        StringBuilder masterBillIds = new StringBuilder();
        for (Map<String, Object> map : listMap) {
            String masterBillId = DataTypeUtil.toNotNullString(map.get("masterBillId"));
            Double amount = DataTypeUtil.toDouble(map.get("amount"), DEFAULT_AMOUNT, 2);

            BMasterBillFlightPojo flightPojo = getBMasterBillFlightPojoById(masterBillId);

            if (flightPojo == null) {
                exceptionInfoStr.append("【" + masterBillId + "】主单对象不存在<br/>");
                continue;
            }

            if (settlementFileType.longValue() == SysConstant.TRANSPORT_COST_SETTLEMENT_FILE_TYPE.longValue()) {
                //  这是结算航空运费
                Double transportCost = DataTypeUtil.toDouble(flightPojo.getTransportCost(), SysConstant.ZERO, 2);
                Double pullDisposeTransportCostAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeTransportCostAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(transportCost, pullDisposeTransportCostAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应航空运费结算金额【" + amount + "】与系统中的对应主单航空运费结算金额【" + transportCost + "+" + pullDisposeTransportCostAmount + "】不一致<br/>");
                }
            } else if (settlementFileType.longValue() == SysConstant.GROUND_AMOUNT_SETTLEMENT_FILE_TYPE.longValue()) {
                // 这是结算地面运费
                Double groundAmount = DataTypeUtil.toDouble(flightPojo.getGroundAmount(), SysConstant.ZERO, 2);
                Double pullDisposeGroundAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeGroundAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(groundAmount, pullDisposeGroundAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应地面运费结算金额【" + amount + "】与系统中的对应主单地面运费结算金额【" + groundAmount + "+" + pullDisposeGroundAmount + "】不一致<br/>");
                }
            } else if (settlementFileType.longValue() == SysConstant.AIRLINES_ADD_COST_SETTLEMENT_FILE_TYPE.longValue()) {
                // 这是结算燃油附加费
                Double airlinesAddCost = DataTypeUtil.toDouble(flightPojo.getAirlinesAddCost(), SysConstant.ZERO, 2);
                Double pullDisposeAirlinesAddCostAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeAirlinesAddCostAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(airlinesAddCost, pullDisposeAirlinesAddCostAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应航空燃油附加费结算金额【" + amount + "】与系统中的对应主单航空燃油附加费结算金额【" + airlinesAddCost + "+" + pullDisposeAirlinesAddCostAmount + "】不一致<br/>");
                }
            } else if (settlementFileType.longValue() == SysConstant.OTHER_CHARGES_SETTLEMENT_FILE_TYPE.longValue()) {
                // 这是结算其他费用
                Double otherCharges = DataTypeUtil.toDouble(flightPojo.getOtherCharges(), SysConstant.ZERO, 2);
                Double pullDisposeOtherChargesAmount = DataTypeUtil.toDouble(flightPojo.getPullDisposeOtherChargesAmount(), SysConstant.ZERO, 2);

                if (amount.doubleValue() == DoubleUtil.sum(otherCharges, pullDisposeOtherChargesAmount, 2)) {
                    masterBillIds.append("'" + masterBillId + "',");
                } else {
                    exceptionInfoStr.append("Excel【" + masterBillId + "】主单号对应其他费用结算金额【" + amount + "】与系统中的对应主单其他费用结算金额【" + otherCharges + "+" + pullDisposeOtherChargesAmount + "】不一致<br/>");
                }
            }
        }

        if (masterBillIds.length() > SysConstant.INT_ZERO) {
            String updateMasterBillIds = masterBillIds.substring(0, masterBillIds.length() - 1);

            // 这个地方再检测对象的所有对账状态，以确保整个对象的全局结算状态
            List<BMasterBillFlightPojo> bMasterBillFlightPojoList = this.bMasterBillFlightMapper.getBMasterBillFlightPojoListByInId(updateMasterBillIds);

            for (BMasterBillFlightPojo flightPojo : bMasterBillFlightPojoList){
                // 航空运费结算状态
                Long transportCostStatusId = DataTypeUtil.toLong(flightPojo.getTransportCostStatusId(),-1);
                // 地面操作费结算状态
                Long groundAmountStatusId = DataTypeUtil.toLong(flightPojo.getGroundAmountStatusId(),-1);
                // 航空附加费结算状态
                Long airlinesAddCostStatusId = DataTypeUtil.toLong(flightPojo.getAirlinesAddCostStatusId(),-1);
                // 其他费用结算状态
                Long otherChargesStatusId = DataTypeUtil.toLong(flightPojo.getOtherChargesStatusId(),-1);
                
                if (settlementFileType.longValue() == SysConstant.TRANSPORT_COST_SETTLEMENT_FILE_TYPE.longValue()) {
                    if(transportCostStatusId.longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()){
                        exceptionInfoStr.append("主单号【"+ flightPojo.getId() +"】【航空运费】已结算，无需重复结算!<br/>");
                    }
                    else{
                        transportCostStatusId = SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId();
                        flightPojo.setTransportCostStatusId(transportCostStatusId);
                        checkFlightPojoSettelementStatus(flightPojo, transportCostStatusId, groundAmountStatusId, airlinesAddCostStatusId, otherChargesStatusId);
                        updatePojo(flightPojo);
                    }
                } else if (settlementFileType.longValue() == SysConstant.GROUND_AMOUNT_SETTLEMENT_FILE_TYPE.longValue()) {
                    if(groundAmountStatusId.longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()){
                        exceptionInfoStr.append("主单号【"+ flightPojo.getId() +"】【地面操作费】已结算，无需重复结算!<br/>");
                    }
                    else{
                        groundAmountStatusId = SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId();
                        flightPojo.setGroundAmountStatusId(groundAmountStatusId);
                        checkFlightPojoSettelementStatus(flightPojo, transportCostStatusId, groundAmountStatusId, airlinesAddCostStatusId, otherChargesStatusId);
                        updatePojo(flightPojo);
                    }
                    
                } else if (settlementFileType.longValue() == SysConstant.AIRLINES_ADD_COST_SETTLEMENT_FILE_TYPE.longValue()) {
                    if(airlinesAddCostStatusId.longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()){
                        exceptionInfoStr.append("主单号【"+ flightPojo.getId() +"】【航空附加费】已结算，无需重复结算!<br/>");
                    }
                    else{
                        airlinesAddCostStatusId = SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId();
                        flightPojo.setAirlinesAddCostStatusId(airlinesAddCostStatusId);
                        checkFlightPojoSettelementStatus(flightPojo, transportCostStatusId, groundAmountStatusId, airlinesAddCostStatusId, otherChargesStatusId);
                        updatePojo(flightPojo);
                    }
                    
                } else if (settlementFileType.longValue() == SysConstant.OTHER_CHARGES_SETTLEMENT_FILE_TYPE.longValue()) {
                    if(otherChargesStatusId.longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()){
                        exceptionInfoStr.append("主单号【"+ flightPojo.getId() +"】【其他费用】已结算，无需重复结算!<br/>");
                    }
                    else{
                        otherChargesStatusId = SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId();
                        flightPojo.setOtherChargesStatusId(otherChargesStatusId);
                        checkFlightPojoSettelementStatus(flightPojo, transportCostStatusId, groundAmountStatusId, airlinesAddCostStatusId, otherChargesStatusId);
                        updatePojo(flightPojo);
                    }
                }
            }
        }

        return exceptionInfoStr.toString();

    }

    private void checkFlightPojoSettelementStatus(BMasterBillFlightPojo flightPojo, Long transportCostStatusId, Long groundAmountStatusId, Long airlinesAddCostStatusId, Long otherChargesStatusId) {
        // 下面核对这个主单的整体结算状态
        if(transportCostStatusId == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                && groundAmountStatusId == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                && airlinesAddCostStatusId == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                && otherChargesStatusId == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
        ){
            flightPojo.setSettlementStatusId(SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId());
        }
    }

}